package cloud.seri.auth.web.rest

import cloud.seri.auth.SeriAuthApp

import cloud.seri.auth.config.SecurityBeanOverrideConfiguration

import cloud.seri.auth.domain.Menu
import cloud.seri.auth.repository.MenuRepository
import cloud.seri.auth.service.MenuService
import cloud.seri.auth.service.dto.MenuDTO
import cloud.seri.auth.service.mapper.MenuMapper
import cloud.seri.auth.web.rest.errors.ExceptionTranslator

import kotlin.test.assertNotNull

import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockitoAnnotations
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.web.PageableHandlerMethodArgumentResolver
import org.springframework.http.MediaType
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.validation.Validator



import cloud.seri.auth.web.rest.TestUtil.createFormattingConversionService
import org.assertj.core.api.Assertions.assertThat
import org.hamcrest.Matchers.hasItem
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

/**
 * Test class for the MenuResource REST controller.
 *
 * @see MenuResource
 */
@RunWith(SpringRunner::class)
@SpringBootTest(classes = [SeriAuthApp::class])
class MenuResourceIT {

    @Autowired
    private lateinit var menuRepository: MenuRepository

    @Autowired
    private lateinit var menuMapper: MenuMapper

    @Autowired
    private lateinit var menuService: MenuService

    @Autowired
    private lateinit var jacksonMessageConverter: MappingJackson2HttpMessageConverter

    @Autowired
    private lateinit var pageableArgumentResolver: PageableHandlerMethodArgumentResolver

    @Autowired
    private lateinit var exceptionTranslator: ExceptionTranslator

    @Autowired
    private lateinit var validator: Validator

    private lateinit var restMenuMockMvc: MockMvc

    private lateinit var menu: Menu

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
        val menuResource = MenuResource(menuService)
        this.restMenuMockMvc = MockMvcBuilders.standaloneSetup(menuResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build()
    }

    @Before
    fun initTest() {
        menuRepository.deleteAll()
        menu = createEntity()
    }

    @Test
    fun createMenu() {
        val databaseSizeBeforeCreate = menuRepository.findAll().size

        // Create the Menu
        val menuDTO = menuMapper.toDto(menu)
        restMenuMockMvc.perform(
            post("/api/menus")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(menuDTO))
        ).andExpect(status().isCreated)

        // Validate the Menu in the database
        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeCreate + 1)
        val testMenu = menuList[menuList.size - 1]
        assertThat(testMenu.text).isEqualTo(DEFAULT_TEXT)
        assertThat(testMenu.i18n).isEqualTo(DEFAULT_I_18_N)
        assertThat(testMenu.group).isEqualTo(DEFAULT_GROUP)
        assertThat(testMenu.link).isEqualTo(DEFAULT_LINK)
        assertThat(testMenu.externalLink).isEqualTo(DEFAULT_EXTERNAL_LINK)
        assertThat(testMenu.target).isEqualTo(DEFAULT_TARGET)
        assertThat(testMenu.icon).isEqualTo(DEFAULT_ICON)
        assertThat(testMenu.disabled).isEqualTo(DEFAULT_DISABLED)
        assertThat(testMenu.hide).isEqualTo(DEFAULT_HIDE)
        assertThat(testMenu.hideInBreadcrumb).isEqualTo(DEFAULT_HIDE_IN_BREADCRUMB)
    }

    @Test
    fun createMenuWithExistingId() {
        val databaseSizeBeforeCreate = menuRepository.findAll().size

        // Create the Menu with an existing ID
        menu.id = "existing_id"
        val menuDTO = menuMapper.toDto(menu)

        // An entity with an existing ID cannot be created, so this API call must fail
        restMenuMockMvc.perform(
            post("/api/menus")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(menuDTO))
        ).andExpect(status().isBadRequest)

        // Validate the Menu in the database
        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeCreate)
    }


    @Test
    fun checkTextIsRequired() {
        val databaseSizeBeforeTest = menuRepository.findAll().size
        // set the field null
        menu.text = null

        // Create the Menu, which fails.
        val menuDTO = menuMapper.toDto(menu)

        restMenuMockMvc.perform(
            post("/api/menus")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(menuDTO))
        ).andExpect(status().isBadRequest)

        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeTest)
    }

    @Test
    fun getAllMenus() {
        // Initialize the database
        menuRepository.save(menu)

        // Get all the menuList
        restMenuMockMvc.perform(get("/api/menus?sort=id,desc"))
            .andExpect(status().isOk)
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(menu.id)))
            .andExpect(jsonPath("$.[*].text").value(hasItem(DEFAULT_TEXT)))
            .andExpect(jsonPath("$.[*].i18n").value(hasItem(DEFAULT_I_18_N)))
            .andExpect(jsonPath("$.[*].group").value(hasItem(DEFAULT_GROUP)))
            .andExpect(jsonPath("$.[*].link").value(hasItem(DEFAULT_LINK)))
            .andExpect(jsonPath("$.[*].externalLink").value(hasItem(DEFAULT_EXTERNAL_LINK)))
            .andExpect(jsonPath("$.[*].target").value(hasItem(DEFAULT_TARGET)))
            .andExpect(jsonPath("$.[*].icon").value(hasItem(DEFAULT_ICON)))
            .andExpect(jsonPath("$.[*].disabled").value(hasItem(DEFAULT_DISABLED)))
            .andExpect(jsonPath("$.[*].hide").value(hasItem(DEFAULT_HIDE)))
            .andExpect(jsonPath("$.[*].hideInBreadcrumb").value(hasItem(DEFAULT_HIDE_IN_BREADCRUMB)))
    }
    
    @Test
    fun getMenu() {
        // Initialize the database
        menuRepository.save(menu)

        val id = menu.id
        assertNotNull(id)

        // Get the menu
        restMenuMockMvc.perform(get("/api/menus/{id}", id))
            .andExpect(status().isOk)
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.id").value(id))
            .andExpect(jsonPath("$.text").value(DEFAULT_TEXT))
            .andExpect(jsonPath("$.i18n").value(DEFAULT_I_18_N))
            .andExpect(jsonPath("$.group").value(DEFAULT_GROUP))
            .andExpect(jsonPath("$.link").value(DEFAULT_LINK))
            .andExpect(jsonPath("$.externalLink").value(DEFAULT_EXTERNAL_LINK))
            .andExpect(jsonPath("$.target").value(DEFAULT_TARGET))
            .andExpect(jsonPath("$.icon").value(DEFAULT_ICON))
            .andExpect(jsonPath("$.disabled").value(DEFAULT_DISABLED))
            .andExpect(jsonPath("$.hide").value(DEFAULT_HIDE))
            .andExpect(jsonPath("$.hideInBreadcrumb").value(DEFAULT_HIDE_IN_BREADCRUMB))
    }

    @Test
    fun getNonExistingMenu() {
        // Get the menu
        restMenuMockMvc.perform(get("/api/menus/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound)
    }

    @Test
    fun updateMenu() {
        // Initialize the database
        menuRepository.save(menu)

        val databaseSizeBeforeUpdate = menuRepository.findAll().size

        // Update the menu
        val id = menu.id
        assertNotNull(id)
        val updatedMenu = menuRepository.findById(id).get()
        updatedMenu.text = UPDATED_TEXT
        updatedMenu.i18n = UPDATED_I_18_N
        updatedMenu.group = UPDATED_GROUP
        updatedMenu.link = UPDATED_LINK
        updatedMenu.externalLink = UPDATED_EXTERNAL_LINK
        updatedMenu.target = UPDATED_TARGET
        updatedMenu.icon = UPDATED_ICON
        updatedMenu.disabled = UPDATED_DISABLED
        updatedMenu.hide = UPDATED_HIDE
        updatedMenu.hideInBreadcrumb = UPDATED_HIDE_IN_BREADCRUMB
        val menuDTO = menuMapper.toDto(updatedMenu)

        restMenuMockMvc.perform(
            put("/api/menus")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(menuDTO))
        ).andExpect(status().isOk)

        // Validate the Menu in the database
        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeUpdate)
        val testMenu = menuList[menuList.size - 1]
        assertThat(testMenu.text).isEqualTo(UPDATED_TEXT)
        assertThat(testMenu.i18n).isEqualTo(UPDATED_I_18_N)
        assertThat(testMenu.group).isEqualTo(UPDATED_GROUP)
        assertThat(testMenu.link).isEqualTo(UPDATED_LINK)
        assertThat(testMenu.externalLink).isEqualTo(UPDATED_EXTERNAL_LINK)
        assertThat(testMenu.target).isEqualTo(UPDATED_TARGET)
        assertThat(testMenu.icon).isEqualTo(UPDATED_ICON)
        assertThat(testMenu.disabled).isEqualTo(UPDATED_DISABLED)
        assertThat(testMenu.hide).isEqualTo(UPDATED_HIDE)
        assertThat(testMenu.hideInBreadcrumb).isEqualTo(UPDATED_HIDE_IN_BREADCRUMB)
    }

    @Test
    fun updateNonExistingMenu() {
        val databaseSizeBeforeUpdate = menuRepository.findAll().size

        // Create the Menu
        val menuDTO = menuMapper.toDto(menu)

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restMenuMockMvc.perform(
            put("/api/menus")
                .contentType(TestUtil.APPLICATION_JSON_UTF8)
                .content(TestUtil.convertObjectToJsonBytes(menuDTO))
        ).andExpect(status().isBadRequest)

        // Validate the Menu in the database
        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeUpdate)
    }

    @Test
    fun deleteMenu() {
        // Initialize the database
        menuRepository.save(menu)

        val databaseSizeBeforeDelete = menuRepository.findAll().size

        val id = menu.id
        assertNotNull(id)

        // Delete the menu
        restMenuMockMvc.perform(
            delete("/api/menus/{id}", id)
                .accept(TestUtil.APPLICATION_JSON_UTF8)
        ).andExpect(status().isNoContent)

        // Validate the database is empty
        val menuList = menuRepository.findAll()
        assertThat(menuList).hasSize(databaseSizeBeforeDelete - 1)
    }

    @Test
    fun equalsVerifier() {
        TestUtil.equalsVerifier(Menu::class.java)
        val menu1 = Menu()
        menu1.id = "id1"
        val menu2 = Menu()
        menu2.id = menu1.id
        assertThat(menu1).isEqualTo(menu2)
        menu2.id = "id2"
        assertThat(menu1).isNotEqualTo(menu2)
        menu1.id = null
        assertThat(menu1).isNotEqualTo(menu2)
    }

    @Test
    fun dtoEqualsVerifier() {
        TestUtil.equalsVerifier(MenuDTO::class.java)
        val menuDTO1 = MenuDTO()
        menuDTO1.id = "id1"
        val menuDTO2 = MenuDTO()
        assertThat(menuDTO1).isNotEqualTo(menuDTO2)
        menuDTO2.id = menuDTO1.id
        assertThat(menuDTO1).isEqualTo(menuDTO2)
        menuDTO2.id = "id2"
        assertThat(menuDTO1).isNotEqualTo(menuDTO2)
        menuDTO1.id = null
        assertThat(menuDTO1).isNotEqualTo(menuDTO2)
    }

    companion object {

        private const val DEFAULT_TEXT: String = "AAAAAAAAAA"
        private const val UPDATED_TEXT = "BBBBBBBBBB"

        private const val DEFAULT_I_18_N: String = "AAAAAAAAAA"
        private const val UPDATED_I_18_N = "BBBBBBBBBB"

        private const val DEFAULT_GROUP: Boolean = false
        private const val UPDATED_GROUP: Boolean = true

        private const val DEFAULT_LINK: String = "AAAAAAAAAA"
        private const val UPDATED_LINK = "BBBBBBBBBB"

        private const val DEFAULT_EXTERNAL_LINK: String = "AAAAAAAAAA"
        private const val UPDATED_EXTERNAL_LINK = "BBBBBBBBBB"

        private const val DEFAULT_TARGET: String = "AAAAAAAAAA"
        private const val UPDATED_TARGET = "BBBBBBBBBB"

        private const val DEFAULT_ICON: String = "AAAAAAAAAA"
        private const val UPDATED_ICON = "BBBBBBBBBB"

        private const val DEFAULT_DISABLED: Boolean = false
        private const val UPDATED_DISABLED: Boolean = true

        private const val DEFAULT_HIDE: Boolean = false
        private const val UPDATED_HIDE: Boolean = true

        private const val DEFAULT_HIDE_IN_BREADCRUMB: Boolean = false
        private const val UPDATED_HIDE_IN_BREADCRUMB: Boolean = true

        /**
         * Create an entity for this test.
         *
         * This is a static method, as tests for other entities might also need it,
         * if they test an entity which requires the current entity.
         */
        @JvmStatic
        fun createEntity(): Menu {
            val menu = Menu(
                text = DEFAULT_TEXT,
                i18n = DEFAULT_I_18_N,
                group = DEFAULT_GROUP,
                link = DEFAULT_LINK,
                externalLink = DEFAULT_EXTERNAL_LINK,
                target = DEFAULT_TARGET,
                icon = DEFAULT_ICON,
                disabled = DEFAULT_DISABLED,
                hide = DEFAULT_HIDE,
                hideInBreadcrumb = DEFAULT_HIDE_IN_BREADCRUMB
            )
            return menu
        }
    }
}
